import { Injectable, Inject } from '@angular/core';
import { Params } from '@angular/router';
import { StorageService, SESSION_STORAGE } from 'ngx-webstorage-service';
import { environment } from 'src/environments/environment';
@Injectable({
  providedIn: 'root'
})
export class FootmarkTrackService {
  private ftKey: string = environment.footmarkTracKey;

  //存储会员浏览地址的路线图
  //用途: 1)后退功能.正向压栈,后退弹栈; 2)获取当前地址的referer 
  constructor(@Inject(SESSION_STORAGE) private storage: StorageService) { }

  /**
   * 保存/压栈
   * @param url 
   */
  public save(url: string): void {
    let data: TrackItem[] = [];
    let lastEle: TrackItem | undefined = undefined;
    if (this.exist()) {
      data = this.get();
      lastEle = data[data.length - 1];
    }
    //不存在 或 存在但一样
    let previousURL: string = lastEle?.value ?? '';
    if (previousURL === url) { //后退时会发生;
      //console.log('[FMT][C1]i back: {prev: ' + previousURL + ', cur: ' + url + '}');
      return;
    }
    let pr: TrackItem = { previous: previousURL, value: url };
    data.push(pr);
    this.storage.set(this.ftKey, data);
  }

  /**
   * 是否忽略地址
   * :/member/login(|register|offline); :/404
   * @param url 
   * @returns
   */
  private isIgnoreURL(url: string): boolean {
    return url.startsWith('/member/login') || url.startsWith('/member/register') || url.startsWith('/member/offline') || url.startsWith('/404');
  }

  /**
   * 是否是第一次保存/栈是否存在
   * @returns
   */
  private exist(): boolean {
    return this.storage.has(this.ftKey);
  }

  /**
   * (2)获取当前地址的Referer
   * 注意:LoginComponent.ngOnInit方法中调用;若在constructor方法中调用会取到错误的值
   * @returns
   */
  public getReferer(): string | null {
    if (!this.exist()) {
      return null;
    }
    //
    let data: TrackItem[] = this.get();
    //栈顶
    let lastEle: TrackItem | undefined = data[data.length - 1];
    return lastEle?.previous ?? null;
  }

  /**
   * 返回存储的数组
   * @returns
   */
  private get(): TrackItem[] {
    return this.storage.get(this.ftKey);
  }

  /**
   * (1)返回前一个地址
   * 注意:方法存在一个缺陷, 例:1>A->login, 2>login->A 此时调用又回到了A,产生在A(2>)上调用回退无作用的假象.getPreviousRef方法修复此缺陷
   * @returns
   */
  public getPrevious(): string | null {
    if (!this.exist()) {
      return null;
    }
    let data: TrackItem[] = this.get();
    //弹栈
    let result: string | null = null;
    do {
      let lastEle: TrackItem | undefined = data.pop();
      if (lastEle && typeof (lastEle.previous) !== 'undefined') {
        result = lastEle.previous;
        if (this.isIgnoreURL(result)) {
          result = null;
        }
      }
    } while (result === null);
    //覆盖掉
    this.storage.set(this.ftKey, data);
    return result;
  }

  /**
   * (1)查看以参考地址为界的前一个地址
   * 修复getPrevious方法在忽略地址前后调用后退无作用的假像
   * @param refUrl 
   * @returns
   */
  public getPreviousRef(refUrl: string): string | null {
    if (!this.exist()) {
      return null;
    }
    let data: TrackItem[] = this.get();
    //地址最后一次出现在哪
    let lastShowIndex: number = -1;
    for (let i: number = data.length - 1; i >= 0; i--) {
      if (data[i].previous === refUrl) {
        lastShowIndex = i;
        break;
      }
    }
    //console.log('[FMT][C2]ref lastshow: ' + lastShowIndex + ', url:' + refUrl);
    //出现过后,开始截取前部分
    if(lastShowIndex > 0){
      data = data.slice(0, lastShowIndex);
    }
    //往前推一级
    let lastEle: TrackItem | undefined = data.pop();
    let result: string | null = lastEle?.previous ?? null;
    //若是忽略的地址再往上推一层
    if (result !== null && this.isIgnoreURL(result)) {
      result = data.pop()?.previous ?? null;
    }
    //覆盖掉
    this.storage.set(this.ftKey, data);
    return result;
  }

  //处理redirect
  public processURL(redirectURL: string): ProcessURLResult {
    let p: any;
    let qs: Params = {};
    if (redirectURL.indexOf('?') == -1) {
      p = redirectURL;
    } else {
      p = redirectURL.substring(0, redirectURL.indexOf('?'));
      let queryString = redirectURL.substring(redirectURL.indexOf('?') + 1);
      if (queryString) {
        let segment: string[] = queryString.split('&');
        segment.forEach(ele => {
          let kv: string[] = ele.split('=');
          if (kv.length == 2) {
            qs[kv[0]] = kv[1];
          }
        });
      }
    }

    return { path: p, queryParams: qs };
  }
}
//单向链表
export interface TrackItem {
  //上一页的连接
  previous: string;
  //当前页的连接
  value: string;
}
export interface ProcessURLResult{
  //路径
  path: string;
  //查询参数
  queryParams: Params
}